home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / utils / mmgr / mcxt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  12.0 KB  |  596 lines

  1. /*
  2.  * mcxt.c --
  3.  *    POSTGRES memory context code.
  4.  */
  5.  
  6. #include <stdio.h>    /* XXX for printf debugging */
  7.  
  8. #include "tmp/c.h"
  9.  
  10. RcsId("$Header: /private/postgres/src/utils/mmgr/RCS/mcxt.c,v 1.15 1991/11/12 20:20:29 mer Exp $");
  11.  
  12. #include "utils/memutils.h"
  13. #include "utils/module.h"
  14. #include "utils/excid.h"
  15.  
  16. #include "nodes/mnodes.h"
  17. #include "nodes/nodes.h"
  18. #include "tags.h"    /* for classTag */
  19.  
  20. #include "utils/mcxt.h"
  21. #include "utils/log.h"
  22.  
  23. #include "utils/palloc.h"
  24.  
  25. extern void bcopy();    /* XXX use header */
  26.  
  27. #undef MemoryContextAlloc
  28. #undef MemoryContextFree
  29. #undef malloc
  30. #undef free
  31.  
  32. /*
  33.  * Global State
  34.  */
  35. static Count MemoryContextEnableCount = 0;
  36. #define MemoryContextEnabled    (MemoryContextEnableCount > 0)
  37.  
  38. static OrderedSetData    ActiveGlobalMemorySetData;    /* uninitialized */
  39. #define ActiveGlobalMemorySet    (&ActiveGlobalMemorySetData)
  40.  
  41. MemoryContext    CurrentMemoryContext = NULL;
  42.  
  43. /*
  44.  * description of allocated memory representation goes here
  45.  */
  46.  
  47. #define PSIZE(PTR)    (*((int32 *)(PTR) - 1))
  48. #define PSIZEALL(PTR)    (*((int32 *)(PTR) - 1) + sizeof (int32))
  49. #define PSIZESKIP(PTR)    ((char *)((int32 *)(PTR) + 1))
  50. #define PSIZEFIND(PTR)    ((char *)((int32 *)(PTR) - 1))
  51. #define PSIZESPACE(LEN)    ((LEN) + sizeof (int32))
  52.  
  53. /*
  54.  * AllocSizeIsValid --
  55.  *    True iff 0 < size and size <= MaxAllocSize.
  56.  */
  57. #define    AllocSizeIsValid(size)    SizeIsInBounds(size, MaxAllocSize)
  58.  
  59. /*
  60.  * PRIVATE DEFINITIONS
  61.  */
  62.  
  63. /*
  64.  * GlobalMemory
  65.  */
  66.  
  67. /*
  68.  * GlobalMemoryAlloc --
  69.  *    Returns pointer to aligned space in the global context.
  70.  *
  71.  * Exceptions:
  72.  *    ExhaustedMemory if allocation fails.
  73.  */
  74. static
  75. Pointer
  76. GlobalMemoryAlloc ARGS((
  77.     GlobalMemory    this,
  78.     Size        size
  79. ));
  80.  
  81. /*
  82.  * GlobalMemoryFree --
  83.  *    Frees allocated memory in the global context.
  84.  *
  85.  * Exceptions:
  86.  *    BadContextErr if current context is not the global context.
  87.  *    BadArgumentsErr if pointer is invalid.
  88.  */
  89. static
  90. void
  91. GlobalMemoryFree ARGS((
  92.     GlobalMemory    this,
  93.     Pointer        pointer
  94. ));
  95.  
  96. /*
  97.  * GlobalMemoryRealloc --
  98.  *    Returns pointer to aligned space in the global context.
  99.  *
  100.  * Note:
  101.  *    Memory associated with the pointer is freed before return.
  102.  *
  103.  * Exceptions:
  104.  *    BadContextErr if current context is not the global context.
  105.  *    BadArgumentsErr if pointer is invalid.
  106.  *    NoMoreMemoryErr if allocation fails.
  107.  */
  108. static
  109. Pointer
  110. GlobalMemoryRealloc ARGS((
  111.     GlobalMemory    this,
  112.     Pointer        pointer,
  113.     Size        size
  114. ));
  115.  
  116. /*
  117.  * GlobalMemoryGetName --
  118.  *    Returns name string for context.
  119.  *
  120.  * Exceptions:
  121.  *    ???
  122.  */
  123. static
  124. String
  125. GlobalMemoryGetName ARGS((
  126.     GlobalMemory    this
  127. ));
  128.  
  129. /*
  130.  * GlobalMemoryDump --
  131.  *    Dumps global memory context for debugging.
  132.  *
  133.  * Exceptions:
  134.  *    ???
  135.  */
  136. static
  137. void
  138. GlobalMemoryDump ARGS((
  139.     GlobalMemory    this
  140. ));
  141.  
  142. /*
  143.  * DumpGlobalMemories --
  144.  *    Dumps all global memory contexts for debugging.
  145.  *
  146.  * Exceptions:
  147.  *    ???
  148.  */
  149. static
  150. void
  151. DumpGlobalMemories ARGS((void));
  152.  
  153.  
  154. /*
  155.  * Global Memory Methods
  156.  */
  157.  
  158. static MemoryContextMethodsData    GlobalContextMethodsData = {
  159.     GlobalMemoryAlloc,    /* Pointer (*)(this, uint32)    palloc */
  160.     GlobalMemoryFree,    /* void (*)(this, Pointer)    pfree */
  161.     GlobalMemoryRealloc,    /* Pointer (*)(this, Pointer)    repalloc */
  162.     GlobalMemoryGetName,    /* String (*)(this)        getName */
  163.     GlobalMemoryDump    /* void (*)(this)        dump */
  164. };
  165.  
  166. /*
  167.  * Note:
  168.  *    TopGlobalMemory is handled specially because of bootstrapping.
  169.  */
  170. /* extern bool EqualGlobalMemory(); */
  171.  
  172. static classObj(GlobalMemory)    TopGlobalMemoryData   = {
  173.     classTag(GlobalMemory),        /* NodeTag        tag       */
  174.     PrintGlobalMemory,        /* (print function)           */
  175.     NULL,                /* (equal function)           */
  176.     NULL,                /* copy function           */
  177.     &GlobalContextMethodsData,    /* ContextMethods    method    */
  178.     { 0 },    /* uninitialized */    /* OrderedSetData    allocSetD */
  179.     "TopGlobal",            /* String        name      */
  180.     { 0 }    /* uninitialized */    /* OrderedElemData    elemD     */
  181. };
  182.  
  183.  
  184. MemoryContext    TopMemoryContext =  (MemoryContext)&TopGlobalMemoryData;
  185.  
  186.  
  187. /*
  188.  * Module State
  189.  */
  190.  
  191. void
  192. EnableMemoryContext(on)
  193.     bool    on;
  194. {
  195.     static bool    processing = false;
  196.  
  197.     AssertState(!processing);
  198.     AssertArg(BoolIsValid(on));
  199.  
  200.     if (BypassEnable(&MemoryContextEnableCount, on)) {
  201.         return;
  202.     }
  203.  
  204.     processing = true;
  205.  
  206.     if (on) {    /* initialize */
  207.         /* initialize TopGlobalMemoryData.setData */
  208.         AllocSetInit(&TopGlobalMemoryData.setData, DynamicAllocMode,
  209.             (Size)0);
  210.  
  211.         /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
  212.         OrderedSetInit(ActiveGlobalMemorySet,
  213.             offsetof(classObj(GlobalMemory), elemData));
  214.         OrderedElemPushInto(&TopGlobalMemoryData.elemData,
  215.             ActiveGlobalMemorySet);
  216.  
  217.         /* initialize CurrentMemoryContext */
  218.         CurrentMemoryContext = TopMemoryContext;
  219.  
  220.     } else {    /* cleanup */
  221.         GlobalMemory    context;
  222.  
  223.         /* walk the list of allocations */
  224.         while (PointerIsValid(context = (GlobalMemory)
  225.                 OrderedSetGetHead(ActiveGlobalMemorySet))) {
  226.  
  227.             if (context == &TopGlobalMemoryData) {
  228.                 /* don't free it and clean it last */
  229.                 OrderedElemPop(&TopGlobalMemoryData.elemData);
  230.             } else {
  231.                 GlobalMemoryDestroy(context);
  232.             }
  233.             /* what is needed for the top? */
  234.         }
  235.  
  236.         /*
  237.          * Freeing memory here should be safe as this is called
  238.          * only after all modules which allocate in TopMemoryContext
  239.          * have been disabled.
  240.          */
  241.  
  242.         /* step through remaining allocations and log */
  243.         /* AllocSetStep(...); */
  244.  
  245.         /* deallocate whatever is left */
  246.         AllocSetReset(&TopGlobalMemoryData.setData);
  247.     }
  248.  
  249.     processing = false;
  250. }
  251.  
  252. Pointer
  253. MemoryContextAlloc(context, size)
  254.     MemoryContext    context;
  255.     Size        size;
  256. {
  257.     AssertState(MemoryContextEnabled);
  258.     AssertArg(MemoryContextIsValid(context));
  259.     AssertArg(SizeIsValid(size));
  260.  
  261.     LogTrap(!AllocSizeIsValid(size), BadAllocSize,
  262.         ((int)"size=%d [0x%x]", size, size));
  263.  
  264.     return (context->method->alloc(context, size));
  265. }
  266.  
  267. void
  268. MemoryContextFree(context, pointer)
  269.     MemoryContext    context;
  270.     Pointer        pointer;
  271. {
  272.     AssertState(MemoryContextEnabled);
  273.     AssertArg(MemoryContextIsValid(context));
  274.     AssertArg(PointerIsValid(pointer));
  275.  
  276.     context->method->free_p(context, pointer);
  277. }
  278.  
  279. extern SLList PallocDebugList;
  280. extern SLList *PallocList;
  281. extern SLList *PfreeList;
  282. extern int PallocDiffTag;
  283. extern bool PallocRecord;
  284. extern bool PallocNoisy;
  285.  
  286. Pointer
  287. MemoryContextAlloc_Debug(file, line, context, size)
  288. String file;
  289. int line;
  290. MemoryContext context;
  291. Size size;
  292. {
  293.     Pointer p;
  294.     PallocDebugData *d, *d1;
  295.  
  296.     AssertState(MemoryContextEnabled);
  297.     AssertArg(MemoryContextIsValid(context));
  298.     AssertArg(SizeIsValid(size));
  299.  
  300.     LogTrap(!AllocSizeIsValid(size), BadAllocSize,
  301.         ((int)"size=%d [0x%x]", size, size));
  302.  
  303.     p = context->method->alloc(context, size);
  304.     if (PallocRecord) {
  305.         d = (PallocDebugData*)malloc(sizeof(PallocDebugData));
  306.         d->pointer = p;
  307.         d->size = size;
  308.         d->line = line;
  309.         d->file = file;
  310.         d->context = MemoryContextGetName(context);
  311.  
  312.         SLNewNode(&(d->Link));
  313.         SLAddTail(&PallocDebugList, &(d->Link));
  314.         if (PallocDiffTag) {
  315.         d1 = (PallocDebugData*)malloc(sizeof(PallocDebugData));
  316.         d1->pointer = p;
  317.         d1->size = size;
  318.         d1->line = line;
  319.         d1->file = file;
  320.         d1->context = d->context;
  321.         SLNewNode(&(d1->Link));
  322.         SLAddTail(PallocList, &(d1->Link));
  323.           }
  324.     }
  325.     if (PallocNoisy)
  326.         printf("!+ f: %s l: %d p: 0x%x s: %d %s\n",
  327.            file, line, p, size, MemoryContextGetName(context));
  328.     return (p);
  329. }
  330.  
  331. void
  332. MemoryContextFree_Debug(file, line, context, pointer)
  333. String file;
  334. int line;
  335. MemoryContext    context;
  336. Pointer        pointer;
  337. {
  338.     PallocDebugData *d;
  339.  
  340.     AssertState(MemoryContextEnabled);
  341.     AssertArg(MemoryContextIsValid(context));
  342.     AssertArg(PointerIsValid(pointer));
  343.  
  344.     if (PallocRecord) {
  345.         d = (PallocDebugData*)SLGetHead(&PallocDebugList);
  346.         while (d != NULL) {
  347.         if (d->pointer == pointer) {
  348.             SLRemove(&(d->Link));
  349.             break;
  350.           }
  351.         d = (PallocDebugData*)SLGetSucc(&(d->Link));
  352.           }
  353.         if (d != NULL) {
  354.         if (PallocDiffTag)
  355.             SLAddTail(PfreeList, &(d->Link));
  356.         else
  357.             free((char *)d);
  358.           }
  359.         else
  360.         elog(NOTICE, "pfree_remove l:%d f:%s p:0x%x %s",
  361.              line, file, pointer, "** not on list **");
  362.        }
  363.     if (PallocNoisy)
  364.         if (d != NULL) {
  365.             printf("!- f: %s l: %d p: 0x%x s: %d %s\n",
  366.                d->file, d->line, pointer, d->size, context);
  367.           }
  368.         else {
  369.             printf("!- f: %s l: %d p: 0x%x s: ? %s\n",
  370.                file, line, pointer, context);
  371.           }
  372.  
  373.     context->method->free_p(context, pointer);
  374. }
  375.  
  376. Pointer
  377. MemoryContextRealloc(context, pointer, size)
  378.     MemoryContext    context;
  379.     Pointer        pointer;
  380.     Size        size;
  381. {
  382.     AssertState(MemoryContextEnabled);
  383.     AssertArg(MemoryContextIsValid(context));
  384.     AssertArg(PointerIsValid(pointer));
  385.     AssertArg(SizeIsValid(size));
  386.  
  387.     LogTrap(!AllocSizeIsValid(size), BadAllocSize,
  388.         ((int)"size=%d [0x%x]", size, size));
  389.  
  390.     return (context->method->realloc(context, pointer, size));
  391. }
  392.  
  393. String
  394. MemoryContextGetName(context)
  395.     MemoryContext    context;
  396. {
  397.     AssertState(MemoryContextEnabled);
  398.     AssertArg(MemoryContextIsValid(context));
  399.  
  400.     return (context->method->getName(context));
  401. }
  402.  
  403. Size
  404. PointerGetAllocSize(pointer)
  405.     Pointer    pointer;
  406. {
  407.     AssertState(MemoryContextEnabled);
  408.     AssertArg(PointerIsValid(pointer));
  409.  
  410.     return (PSIZE(pointer));
  411. }
  412.  
  413. MemoryContext
  414. MemoryContextSwitchTo(context)
  415.     MemoryContext    context;
  416. {
  417.     MemoryContext    old;
  418.  
  419.     AssertState(MemoryContextEnabled);
  420.     AssertArg(MemoryContextIsValid(context));
  421.  
  422.     old = CurrentMemoryContext;
  423.     CurrentMemoryContext = context;
  424.     return (old);
  425. }
  426.  
  427. /*
  428.  * START HERE
  429.  *    Add routines to move memory between contexts.
  430.  */
  431.  
  432. void
  433. MemoryContextDump(context)
  434. MemoryContext context;
  435. {
  436.     context->method->dump(context);
  437. }
  438.  
  439. /*
  440.  * DEBUGGING
  441.  */
  442. void
  443. DumpMemoryContexts()
  444. {
  445.     if (!MemoryContextEnabled) {
  446.         printf("!MemoryContextEnabled\n");
  447.         return;
  448.     }
  449.  
  450.     DumpGlobalMemories();
  451. /*
  452.  *  There should also be a standard log interface (DEBUG).
  453.  *
  454.  *  Also, add file pcxt for the portal memory context (and gcxt?).
  455.  *
  456.  */
  457.  
  458.  
  459. }
  460.  
  461. /*
  462.  * External Functions
  463.  */
  464.  
  465. GlobalMemory
  466. CreateGlobalMemory(name)
  467.     String    name;    /* XXX MemoryContextName */
  468. {
  469.     GlobalMemory    context;
  470.     MemoryContext    savecxt;
  471.  
  472.     AssertState(MemoryContextEnabled);
  473.     AssertArg(StringIsValid(name));    /* XXX MemoryContextName */
  474.  
  475.     savecxt = MemoryContextSwitchTo(TopMemoryContext);
  476.     
  477.     context = CreateNode(GlobalMemory);
  478.     context->method = &GlobalContextMethodsData;
  479.     context->name = name;        /* assumes name is static */
  480.     AllocSetInit(&context->setData, DynamicAllocMode, (Size)0);
  481.  
  482.     /* link the context */
  483.     OrderedElemPushInto(&context->elemData, ActiveGlobalMemorySet);
  484.  
  485.     MemoryContextSwitchTo(savecxt);
  486.     return (context);
  487. }
  488.  
  489. void
  490. GlobalMemoryDestroy(context)
  491.     GlobalMemory    context;
  492. {
  493.     AssertState(MemoryContextEnabled);
  494.     AssertArg(ExactNodeType(context,GlobalMemory));
  495.     AssertArg(context != &TopGlobalMemoryData);
  496.  
  497.     AllocSetReset(&context->setData);
  498.  
  499.     /* unlink and delete the context */
  500.     OrderedElemPop(&context->elemData);
  501. #ifdef PALLOC_DEBUG
  502.     MemoryContextFree_Debug(__FILE__, __LINE__, 
  503.                 TopMemoryContext, (Pointer)context);
  504. #else
  505.     MemoryContextFree(TopMemoryContext, (Pointer)context);
  506. #endif
  507. }
  508.  
  509. /*
  510.  * PRIVATE
  511.  */
  512.  
  513. static
  514. Pointer
  515. GlobalMemoryAlloc(this, size)
  516.     GlobalMemory    this;
  517.     Size        size;
  518. {
  519.     return (AllocSetAlloc(&this->setData, size));
  520. }
  521.  
  522. static
  523. void
  524. GlobalMemoryFree(this, pointer)
  525.     GlobalMemory    this;
  526.     Pointer        pointer;
  527. {
  528.     AllocSetFree(&this->setData, pointer);
  529. }
  530.  
  531. static
  532. Pointer
  533. GlobalMemoryRealloc(this, pointer, size)
  534.     GlobalMemory    this;
  535.     Pointer        pointer;
  536.     Size        size;
  537. {
  538.     return (AllocSetRealloc(&this->setData, pointer, size));
  539. }
  540.  
  541. static
  542. String
  543. GlobalMemoryGetName(this)
  544.     GlobalMemory    this;
  545. {
  546.     return (this->name);
  547. }
  548.  
  549. static
  550. void
  551. GlobalMemoryDump(this)
  552.     GlobalMemory    this;
  553. {
  554.     GlobalMemory    context;
  555.  
  556.     printf("--\n%s:\n", GlobalMemoryGetName(this));
  557.  
  558.     context = (GlobalMemory)OrderedElemGetPredecessor(&this->elemData);
  559.     if (PointerIsValid(context)) {
  560.         printf("\tpredecessor=%s\n", GlobalMemoryGetName(context));
  561.     }
  562.  
  563.     context = (GlobalMemory)OrderedElemGetSuccessor(&this->elemData);
  564.     if (PointerIsValid(context)) {
  565.         printf("\tsucessor=%s\n", GlobalMemoryGetName(context));
  566.     }
  567.  
  568.     AllocSetDump(&this->setData);    /* XXX is this right interface */
  569. }
  570.  
  571. static
  572. void
  573. DumpGlobalMemories()
  574. {
  575.     GlobalMemory    context;
  576.  
  577.     context = (GlobalMemory)OrderedSetGetHead(&ActiveGlobalMemorySetData);
  578.  
  579.     while (PointerIsValid(context)) {
  580.         GlobalMemoryDump(context);
  581.  
  582.         context = (GlobalMemory)OrderedElemGetSuccessor(
  583.             &context->elemData);
  584.     }
  585. }
  586.  
  587. /* 
  588.  *    MemoryContextIsValid(context) is now a macro in mnodes.h -cim 4/27/91
  589.  */
  590.  
  591. void
  592. PrintGlobalMemory(foo)
  593.      GlobalMemory foo;
  594. {
  595. }
  596.